#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <stdarg.h>
#include <string.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)

int printf(const char *fmt, ...) {
    va_list ap;
    int ret = -1;
    va_start(ap, fmt);
    ret = vprintf(fmt, ap);
    va_end(ap);
    return ret;  
}

int vprintf(const char *fmt, va_list ap) {
int ret = 0;
char *s;
long n;
char buf[65];
	while (*fmt != '\0'){
		if (*fmt == '%'){
			fmt++;
			switch(*fmt){	
				case 'c':{
					putch(va_arg(ap,int));//取下一个参数的字符，并打印
                			ret++;
                			break;		
					 }
				case 's':{
					s = (char*)va_arg(ap,char *);
					while(*s != '\0')//利用解引用进行输出
					{       
			                    putch(*s);
					    ret++;
					    s++;
					}
				         break;
					 }
				case 'd':{
					 n = va_arg(ap,int);
					 if (n < 0){
					 	putch('-');
						n =-n;
//						putch('n');
					 }
					 itoa(n,buf);
//					 putch('\n');
//					 putch('f');
//					 for(int i =0;i<strlen(buf);i++)putch(buf[i]);
					 int i = 0;
					while(buf[i] != '\0')//利用解引用进行输出
					{       
			                    putch(buf[i]);
					    ret++;
					    i++;
					}
					 break;
					 }
				case 'x':{
					 n = va_arg(ap,int);
					 if (n < 0){
					 	putch('-');
						n =-n;
//						putch('n');
					 }
					 itoahex(n,buf);
//					 putch('\n');
//					 putch('f');
//					 for(int i =0;i<strlen(buf);i++)putch(buf[i]);
					 int i = 0;
					while(buf[i] != '\0')//利用解引用进行输出
					{       
			                    putch(buf[i]);
					    ret++;
					    i++;
					}
					 break;
					 }
				case 'p':{
					 n = va_arg(ap,long);
					 if (n < 0){
					 	putch('-');
						n =-n;
//						putch('n');
					 }
					 itoahex(n,buf);
//					 putch('\n');
//					 putch('f');
//					 for(int i =0;i<strlen(buf);i++)putch(buf[i]);
					 int i = 0;
					while(buf[i] != '\0')//利用解引用进行输出
					{       
			                    putch(buf[i]);
					    ret++;
					    i++;
					}
					 break;
					 }

		                   case 'l':
				   fmt++;
			           switch(*fmt){
				     case 'd':{
					   n = va_arg(ap,long);
					   if (n < 0){
					 	putch('-');
						n =-n;
//						putch('n');
					   } 
					   itoa(n,buf);
//					 putch('\n');
//					 putch('f');
//					 for(int i =0;i<strlen(buf);i++)putch(buf[i]);
					   int i = 0;
					  while(buf[i] != '\0')//利用解引用进行输出
					  {       
			                      putch(buf[i]);
					      ret++;
					      i++;
				          }
					   break;
					  }
					  case 'x':{
					  n = va_arg(ap,long);
					  if (n < 0){
					 	putch('-');
						n =-n;
//						putch('n');
					  }
					  itoahex(n,buf);
//					 putch('\n');
//					 putch('f');
//					 for(int i =0;i<strlen(buf);i++)putch(buf[i]);
					 int i = 0;
					while(buf[i] != '\0')//利用解引用进行输出
					{       
			                    putch(buf[i]);
					    ret++;
					    i++;
					}
					 break;
					 }
				  }
			}
		}
		else{
			putch(*fmt);
			ret++;
			if(*fmt == '\n'){}

		}
		fmt++;
	}
	return ret;
}

int vsprintf(char *out, const char *fmt, va_list ap) {
char buf [65];
long n;
char *s;
int ret = 0;
	while (*fmt != '\0'){
		if (*fmt == '%'){
			fmt++;
			switch(*fmt){
				case 'd':{
					 n = va_arg(ap,int);
					 if (n < 0){
					 	*out = '-';
						out++;
						n =-n;
//						putch('n');
					 }
					 itoa(n,buf);
//					 putch('\n');
//					 putch('f');
//					 for(int i =0;i<strlen(buf);i++)putch(buf[i]);
//					 putch('\n');
					 memcpy(out,buf,strlen(buf));
					 out += strlen(buf);
					 *out = '\0';
					 break;
					 }
				case 's':{
				 	 s = va_arg(ap,char *);
					// putch('f');
					// putch('\n');
//					 for(int i =0;i<strlen(s);i++)putch(*(s+i));
//					 putch('f');
					 memcpy(out,s,strlen(s));
					 out += strlen(s);
					 *out = '\0';
					 break;
					 }
			}
		}
		else{
			*out = *fmt;
			 out++;
			 *out = '\0';
			if(*fmt == '\n'){
			}

		}
		fmt++;
	}
	return ret;
}

int sprintf(char *out, const char *fmt, ...) {
    va_list ap;
    int ret = -1;
    va_start(ap, fmt);
    ret = vsprintf(out, fmt, ap);
    va_end(ap);
    return ret;
}

int snprintf(char *out, size_t n, const char *fmt, ...) {
	  panic("Not implemented");

}

int vsnprintf(char *out, size_t n, const char *fmt, va_list ap) {
  panic("Not implemented");
}




#endif
